package com.lzqinga.service.storage;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;

/**
 * - @author lzqinga
 * - @description
 * - @date 2025/10/11/011 11:54
 **/
@Slf4j
@Service
public class LocalStorageService {

    @Value("${app.storage.base-dir}")
    private String baseDir;

    @Value("${app.storage.images-dir}")
    private String imagesDir;

    @Value("${app.storage.audio-dir}")
    private String audioDir;

    @Value("${app.storage.segments-dir}")
    private String segmentsDir;

    @Value("${app.storage.output-dir}")
    private String outputDir;

    @Value("${app.storage.temp-dir}")
    private String tempDir;

    /**
     * 初始化存储目录
     */
    public void initStorageDirs() {
        try {
            createDirIfNotExists(baseDir);
            createDirIfNotExists(imagesDir);
            createDirIfNotExists(audioDir);
            createDirIfNotExists(segmentsDir);
            createDirIfNotExists(outputDir);
            createDirIfNotExists(tempDir);
            log.info("存储目录初始化完成");
        } catch (Exception e) {
            log.error("初始化存储目录失败", e);
            throw new RuntimeException("存储目录初始化失败");
        }
    }

    /**
     * 保存图片文件
     */
    public String saveImage(MultipartFile imageFile) {
        return saveFile(imageFile, imagesDir, "img");
    }

    /**
     * 保存音频文件
     */
    public String saveAudio(MultipartFile audioFile) {
        return saveFile(audioFile, audioDir, "audio");
    }

    /**
     * 保存视频片段
     */
    public String saveVideoSegment(File videoFile, String prefix) {
        try {
            String fileName = prefix + "_" + System.currentTimeMillis() + ".mp4";
            String filePath = segmentsDir + File.separator + fileName;

            Files.copy(videoFile.toPath(), Paths.get(filePath));
            log.info("视频片段保存成功: {}", filePath);
            return filePath;
        } catch (Exception e) {
            log.error("保存视频片段失败", e);
            throw new RuntimeException("保存视频片段失败: " + e.getMessage());
        }
    }

    /**
     * 保存最终视频
     */
    public String saveFinalVideo(File videoFile, String fileName) {
        try {
            String filePath = outputDir + File.separator + fileName;
            Files.copy(videoFile.toPath(), Paths.get(filePath));
            log.info("最终视频保存成功: {}", filePath);
            return filePath;
        } catch (Exception e) {
            log.error("保存最终视频失败", e);
            throw new RuntimeException("保存最终视频失败: " + e.getMessage());
        }
    }

    /**
     * 生成临时文件路径
     */
    public String generateTempFilePath(String prefix, String extension) {
        String fileName = prefix + "_" + UUID.randomUUID() + "." + extension;
        return tempDir + File.separator + fileName;
    }

    /**
     * 获取输出目录路径
     */
    public String getOutputDir() {
        return outputDir;
    }

    /**
     * 获取临时目录路径
     */
    public String getTempDir() {
        return tempDir;
    }

    /**
     * 清理临时文件
     */
    public void cleanupTempFiles() {
        try {
            File tempDirFile = new File(tempDir);
            if (tempDirFile.exists() && tempDirFile.isDirectory()) {
                File[] files = tempDirFile.listFiles();
                if (files != null) {
                    for (File file : files) {
                        if (file.isFile()) {
                            boolean deleted = file.delete();
                            if (deleted) {
                                log.debug("删除临时文件: {}", file.getAbsolutePath());
                            }
                        }
                    }
                }
            }
            log.info("临时文件清理完成");
        } catch (Exception e) {
            log.warn("清理临时文件失败", e);
        }
    }

    /**
     * 通用文件保存方法
     */
    private String saveFile(MultipartFile file, String targetDir, String prefix) {
        try {
            createDirIfNotExists(targetDir);

            String originalFilename = file.getOriginalFilename();
            String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String fileName = prefix + "_" + UUID.randomUUID() + fileExtension;
            String filePath = targetDir + File.separator + fileName;

            File dest = new File(filePath);
            file.transferTo(dest);

            log.info("文件保存成功: {}", filePath);
            return filePath;
        } catch (Exception e) {
            log.error("文件保存失败", e);
            throw new RuntimeException("文件保存失败: " + e.getMessage());
        }
    }

    /**
     * 创建目录（如果不存在）
     */
    private void createDirIfNotExists(String dirPath) throws IOException {
        Path path = Paths.get(dirPath);
        if (!Files.exists(path)) {
            Files.createDirectories(path);
            log.debug("创建目录: {}", dirPath);
        }
    }

    /**
     * 检查文件是否存在
     */
    public boolean fileExists(String filePath) {
        return Files.exists(Paths.get(filePath));
    }

    /**
     * 获取文件大小
     */
    public long getFileSize(String filePath) {
        try {
            return Files.size(Paths.get(filePath));
        } catch (IOException e) {
            log.warn("获取文件大小失败: {}", filePath, e);
            return 0;
        }
    }
}
